package com.minstone.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;

/**
 * <p>Title: ���߰�</p>
 *
 * <p>Description: �����๤��</p>
 *
 * <p>Copyright: MinStone Copyright (c) 2012</p>
 *
 * <p>Company: �����Ƽ����޹�˾</p>
 *
 * @author angeo
 * @version 1.0
 */
public class ClassUtil {
	private static final Logger LOGGER = Logger.getLogger(ClassUtil.class);
	
	/**
	 * ��ȡ������
	 * 
	 * @param fieldName���������
	 * @param type����ȡ���Է�����ʶ��get/set��
	 * @return����ȡ������
	 */
	public static String getMethodName(String fieldName, String type) {
		char c = fieldName.charAt(0);
		if (c > 90) {// ����ĸת���ɴ�д
			c = (char) (c - 32);
			fieldName = c + fieldName.substring(1);
		}
		String methodName = type + fieldName;
		return methodName;
	}

	/**
	 * Ϊ����ֵ
	 * 
	 * @param obj����Ҫ��ֵ�Ķ���
	 * @param fieldName���ֶ��������
	 * @param fieldValue���ֶ�����ֵ
	 * @return������ֵ��Ķ���
	 * @throws Exception
	 */
	public static Object setFiledValue(Object obj, String fieldName,
			Object fieldValue) {
		if(fieldValue==null) return obj;
		// ��ȡ�������ֵ������
		String methodName = getMethodName(fieldName, "set");
		// ���÷����ȡ����
		Method method = null;
		try {
			method = obj.getClass().getMethod(methodName,
					new Class[] { fieldValue.getClass() });
		} catch (NoSuchMethodException e) {
			LOGGER.error(e.getMessage(), e);
			try {
				method = obj.getClass().getMethod(methodName,
						new Class[] { ClassUtil.getNumberObjectClass(fieldValue) });
				// ����ִ�з���
				method.invoke(obj, new Object[] { fieldValue });
				return obj;
			} catch (Exception e2) {
				LOGGER.error(e2.getMessage(), e2);
			}
		}
		try {
			// ����ִ�з���
			if (method != null) {
				method.invoke(obj, new Object[] { fieldValue });
			}
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		return obj;
	}
	
	/**
	 * Ϊ����ֵ
	 * 
	 * @param obj����Ҫ��ֵ�Ķ���
	 * @param fieldName���ֶ��������
	 * @param fieldValue���ֶ�����ֵ
	 * @return������ֵ��Ķ���
	 * @throws Exception
	 */
	public static Object setFiledValue(Object obj, Field field,
			Object fieldValue) {
		String fieldName = field.getName();
		// ��ȡ�������ֵ������
		String methodName = getMethodName(fieldName, "set");
		try {
			// ���÷����ȡ����
			Method method = obj.getClass().getMethod(methodName,
					new Class[] { field.getType() });
			// ����ִ�з���
			method.invoke(obj, new Object[] { getFieldObjectValue(field, (String)fieldValue) });
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
		}
		return obj;
	}
	
	
	/**
	 * ��ȡ�����ж�Ӧ�����ֶ�ֵ
	 * 
	 * @param obj����ȡ����
	 * @param fieldName�����������ֶ���
	 * @return�����ظö����ϣ����������ֶ�ֵ
	 * @throws Exception
	 */
	public static String getFiledValue(Object obj, String fieldName) {
		Object value = getFiledValueObject(obj, fieldName);
		String fieldValue = "";
		if(value!=null) fieldValue = value.toString();
		return fieldValue;
	}
	
	/**
	 * ��ȡ�����ж�Ӧ�����ֶ�ֵ
	 * 
	 * @param obj����ȡ����
	 * @param fieldName�����������ֶ���
	 * @return�����ظö����ϣ����������ֶ�ֵ
	 * @throws Exception
	 */
	public static Object getFiledValueObject(Object obj, String fieldName) {
		// ��ȡ����
		Class className = obj.getClass();
		// ��ȡ��������
		Field[] field = className.getDeclaredFields();
		Object fieldValue = null;
		for (int i = 0; i < field.length; i++) { // ѭ������
			if (fieldName.equals(field[i].getName())) { // ���ҳ���Ӧ�������ֶ�
				// ��ȡGET�����ֶη�����
				String methodName = getMethodName(fieldName, "get");
				try {
					if(obj.getClass().getDeclaredField(fieldName).getType().equals(boolean.class)){
						
						 methodName = getMethodName(fieldName, "is");
					}
					
					// ���÷��䣬��ȡ�÷���
					Method method = className.getDeclaredMethod(methodName,
							new Class[] {});
					// ִ�з���
					fieldValue = method.invoke(obj, new Object[] {});
					break;
				} catch (Exception e) {
					LOGGER.error(e.getMessage(), e);
				}
			}
		}
		return fieldValue;
	}
	
	/**
	 * ��ȡ�ö���ļ�����
	 * @param obj
	 * @return
	 */
	public static String getSimpleName(Object obj) {
		String[] name = obj.getClass().getName().split("\\.");
		return name[name.length-1];
	}
	
	/**
	 * ��ȡ������������
	 * @param obj
	 * @return
	 */
	public static Field[] getFieldes(Object obj) {
		return obj.getClass().getDeclaredFields();
	}
	
	/**
	 * ��ȡ�������ͼ��
	 * @param field
	 * @return
	 */
	public static String getFieldClassName(Field field) {
		String[] fieldStr = field.getType().toString().split("\\.");
		return fieldStr[fieldStr.length-1];
	}
	
	/**
	 * ��ʽ�������ظ����Ե�����
	 * @param field
	 * @param fieldValue
	 * @return
	 * @throws ParseException
	 */
	public static Object getFieldObjectValue(Field field, String fieldValue) throws ParseException {
		String fieldValueClass = getFieldClassName(field);
		if(fieldValueClass.equals("String")) return fieldValue;
		Object fieldObjValue = new Object();
		if(fieldValueClass.equals("int") || fieldValueClass.equals("Integer")) {
//			fieldObjValue = Integer.valueOf(fieldValue);
			fieldObjValue = new Integer(fieldValue);
		}else if(fieldValueClass.equals("long") || fieldValueClass.equals("Long")){
//			fieldObjValue = Long.valueOf(fieldValue);
			fieldObjValue = new Long(fieldValue);
		}else if(fieldValueClass.equals("boolean")){
			
			fieldObjValue=new Boolean(fieldValue);
			
		}else if(fieldValueClass.equals("float") || fieldValueClass.equals("Float")){
//			fieldObjValue = Float.valueOf(fieldValue);
			fieldObjValue = new Float(fieldValue);
		}else if(fieldValueClass.equals("double") || fieldValueClass.equals("Double")){
//			fieldObjValue = Double.valueOf(fieldValue);
			fieldObjValue = new Double(fieldValue);
		}else if(fieldValueClass.equals("Timestamp")){
			fieldObjValue = Timestamp.valueOf(fieldValue);
		}else if(fieldValueClass.equals("Date")){
			String[] fieldStr = field.getType().toString().split("\\.");
			if(fieldStr[fieldStr.length-2].equals("sql"))
				fieldObjValue = java.sql.Date.valueOf(fieldValue);
			else {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				fieldObjValue = sdf.parse(fieldValue);
			}
		}	
		return fieldObjValue;
	}
	
	/**
	 * ���ػ�������Ͷ���Ļ��������
	 * @param obj������
	 * @return�������磺java.lang.Long-->long.class��
	 * @throws NoSuchFieldException 
	 * @throws SecurityException 
	 */
	public static Class getNumberObjectClass(Object obj) throws SecurityException, NoSuchFieldException {
		String className = getSimpleName(obj);
		if(className.equals("Long")) return long.class;
		if(className.equals("Integer")) return int.class;
		if(className.equals("Double")) return double.class;
		if(className.equals("Byte")) return byte.class;
		if(className.equals("Float")) return float.class;
		if(className.equals("Boolean"))return boolean.class;
		return null;
	}
	
	/**
	 * ������ݶ���Ļ�����ֵ
	 * @param number
	 * @return
	 * @throws Exception 
	 */
	public static Object getNumberObjectValue(Object number) {
		String className = getSimpleName(number);
		className = upOrDownFieldWord(className);
		String metnodName = className + "Value";
		Method method = null;
		try {
			method = number.getClass().getMethod(metnodName, new Class[]{});
			return method.invoke(number, new Object[]{});
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			// TODO: handle exception
		}
		return method;
	}
	
	public static String upOrDownFieldWord(String fieldName) {
		char c = fieldName.charAt(0);
		if (c > 90) {// ����ĸת���ɴ�д
			c = (char) (c - 32);
		} else {
			c = (char) (c + 32);
		}
		fieldName = c + fieldName.substring(1);
		return fieldName;
	}
}
